﻿package net.sapfree.core.base;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import net.sapfree.core.db.PagingInfo;
import net.sapfree.core.db.Record;
import net.sapfree.core.db.RecordSet;
import net.sapfree.core.web.ExceptionHandler;
import net.sapfree.core.web.RequestKit;


public abstract class ServletBase extends HttpServlet
{
	private static final long serialVersionUID = 8355925996675325169L;
	private static ThreadLocal<HttpServletRequest> m_request   = new ThreadLocal<HttpServletRequest>();
	private static ThreadLocal<HttpServletResponse> m_response = new ThreadLocal<HttpServletResponse>();

	protected final void forward(String url) throws ServletException, IOException
	{
		(m_request.get().getRequestDispatcher(url)).forward(m_request.get(), m_response.get());
	}
	
	protected final void forwardIgnoreException(String url)
	{
		try
		{
			(m_request.get().getRequestDispatcher(url)).forward(m_request.get(), m_response.get());
		}
		catch (Exception e)
		{
			ExceptionHandler.handleException(e, m_request.get(), m_response.get());
		}
	}
	
	public final void redirect(String url) throws IOException
	{
		m_response.get().sendRedirect(url);
	}
	
	public final void redirectIgnoreException(String url)
	{
		try
		{
			m_response.get().sendRedirect(url);
		}
		catch (Exception e)
		{
			ExceptionHandler.handleException(e, m_request.get(), m_response.get());
		}
	}
	
	public final void doGet(HttpServletRequest request, HttpServletResponse response)	throws ServletException, IOException
	{

		doPost(request, response);
	}

	public final void doPost(HttpServletRequest request, HttpServletResponse response)	throws ServletException, IOException 
	{
		try 
		{
			m_request.set(request);
			m_response.set(response);
			RequestKit requestKit = new RequestKit(request);
			request.setAttribute("RequestKit",requestKit);
			performTask(request, response);
		} catch (Exception e)
		{
			ExceptionHandler.handleException(e, m_request.get(), m_response.get());
		}
	}
	
	protected final void appendString(String s) throws IOException
	{
		m_response.get().setContentType("text/html;charset=UTF-8");
		PrintWriter pw;
		pw = m_response.get().getWriter();
		pw.write(s);
		pw.close();
	}
	
	protected void appendSuccessResult(String s)
	{
		try
		{
			if(s == null || s.startsWith("{"))
				appendString("{result:'success',data:"+s+"}");
			else
				appendString("{result:'success',data:'"+s+"'}");
		} 
		catch (Exception e)
		{
			appendStringIgnoreException("{result:'error',data:'"+e.toString()+"'}");
		}
	}
	
	protected void appendErrorResult(String s)
	{
		if(s == null || s.startsWith("{"))
			appendStringIgnoreException("{result:'error',data:"+s+"}");
		else
			appendStringIgnoreException("{result:'error',data:'"+s+"'}");
	}
	
	protected final void appendStringIgnoreException(String s)
	{

		try
		{
			m_response.get().setContentType("text/html;charset=UTF-8");
			PrintWriter pw;
			pw = m_response.get().getWriter();
			pw.write(s);
			pw.close();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}

	}
	
	protected void appendReocrdJson(Record record)
	{
		StringBuffer sb = new StringBuffer();
		sb.append("{'result':'success','data':").append(record == null ? "null" : record.getJsonString()).append("}");
		try
		{
			appendString(sb.toString());
		}
		catch (IOException e)
		{
			e.printStackTrace();
			appendStringIgnoreException("{'result':error,'data':'"+e.toString()+"'}");
		}
	}
	
	protected void appendReocrdSetJson(RecordSet recordSet)
	{
		StringBuffer sb = new StringBuffer();
		sb.append("{'result':'success','data':").append(recordSet == null ? "null" : recordSet.getJsonString()).append("}");
		try
		{
			appendString(sb.toString());
		}
		catch (IOException e)
		{
			e.printStackTrace();
			appendStringIgnoreException("{'result':error,'data':'"+e.toString()+"'}");
		}
	}
	
	protected void appendData4Grid(RecordSet recordSet, PagingInfo pagingInfo)
	{
		try
		{
			StringBuffer sb = new StringBuffer();
			sb.append("{");
			sb.append("'data':").append(recordSet == null ? "[]":recordSet.getJsonString());
			if(pagingInfo != null)
			{
				sb.append(",'paging':").append(pagingInfo.getJsonString());
			}
			sb.append(",'grid_attr':{");
			if(recordSet != null)
			{
				String rawSql = recordSet.getRawSQL();
				sb.append("'grid_raw_sql':'").append(rawSql.replaceAll("\\\\", "\\\\\\\\").replaceAll("'", "\\\\'").replaceAll("\"", "\\\\\"")).append("'");
			}
			sb.append("}}");
			appendString(sb.toString());
		} 
		catch (Exception e)
		{
			appendStringIgnoreException(e.toString());
		}
	}
	
	public void goback(HttpServletRequest request, HttpServletResponse response)
	{
		try
		{
			String ctx = request.getContextPath();
			request.getRequestDispatcher(ctx + "/jsp/common/goback.jsp").forward(request, response);
		}
		catch (Exception e)
		{
			ExceptionHandler.handleException(e, request, response );
		}
	}
	
	protected void defaultAction(HttpServletRequest request, HttpServletResponse response) throws IOException
	{
		appendString("the parameter method is missed.");
	}

	protected void performTask(HttpServletRequest request,
			HttpServletResponse response) throws Exception
	{
		String action = request.getParameter("method");

		try 
		{
			if(action == null || "".equals(action))
			{
				defaultAction(request, response);
				return ;
			}
			Class[] paramTypes = {
					Class.forName("javax.servlet.http.HttpServletRequest"),
					Class.forName("javax.servlet.http.HttpServletResponse") };
			Method method = getClass().getMethod(action, paramTypes);
			Object[] paramValues = { request, response };
			method.invoke(this, paramValues);

		}
		catch(NoSuchMethodException e)
		{
			appendString(getClass().getSimpleName() + " has no public method named '"+action+"', or the parameter 'method' is wrong.");
		}
		catch(InvocationTargetException e)
		{
			ExceptionHandler.handleException((Exception) e.getTargetException(), request, response );
		}
		catch (Exception e)
		{
			ExceptionHandler.handleException(e, request, response );
		}
	}
	
	public int getUploadLimitedSize() {
		return 1024 * 1024 * 2;
	}
	
	protected MultiPartRequest getRequestParser(HttpServletRequest request) {
		try {
			MultiPartRequest parser = null; 
			javax.servlet.ServletContext context = getServletContext();
			parser = null;
			parser = new MultiPartRequest(context, request);
			parser.setAllowedTotalSize(getUploadLimitedSize());
			
			int result = parser.parseAndSave();
			if (result == 1) {
				new Exception("上传文件大小超过限制!");
				return null;
			}
	
			return parser;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		} catch (ServletException ex) {
			ex.printStackTrace();
			return null;
		}
	}
}
